package com.guosen.zebra.gateway.route.router;

import com.guosen.zebra.core.common.ZebraConstants;
import com.guosen.zebra.gateway.route.cache.UrlPrefixRouteCache;
import com.guosen.zebra.gateway.route.model.RouteInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 模糊匹配路由
 */
@Component
public class FuzzyRouter {
    private static final Logger LOGGER = LoggerFactory.getLogger(FuzzyRouter.class);

    /**
     * 路由
     * @param requestURI    请求 URI
     * @return  路由信息
     */
    public RouteInfo route(String requestURI) {
        RouteInfo configFuzzyMatchRouteInfo = fuzzyMatch(requestURI);
        if (configFuzzyMatchRouteInfo == null) {
            // 找不到了，那只能返回了
            return null;
        }

        String methodName = getMethodName(requestURI, configFuzzyMatchRouteInfo.getUrlPrefix());
        if (StringUtils.isEmpty(methodName)) {
            return null;
        }

        RouteInfo fuzzyMatchRouteInfo = RouteInfo.newBuilder()
                .serviceName(configFuzzyMatchRouteInfo.getServiceName())
                .group(configFuzzyMatchRouteInfo.getGroup())
                .method(methodName)
                .version(configFuzzyMatchRouteInfo.getVersion())
                .build();

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Route request URI [{}] to service [{}]", requestURI, fuzzyMatchRouteInfo);
        }

        return fuzzyMatchRouteInfo;
    }

    private static RouteInfo fuzzyMatch(String requestURI) {
        RouteInfo matchRouteInfo = null;

        Map<String, RouteInfo> urlPrefixRouteInfoMap = UrlPrefixRouteCache.getInstance().getUrlPrefixRouteInfo();
        for (Map.Entry<String, RouteInfo> urlPrefixRouteInfo : urlPrefixRouteInfoMap.entrySet()) {
            String urlPrefix = urlPrefixRouteInfo.getKey();
            RouteInfo routeInfo = urlPrefixRouteInfo.getValue();

            if (requestURI.startsWith(urlPrefix)) {
                matchRouteInfo = routeInfo;
                break;
            }
        }

        return matchRouteInfo;
    }

    private static String getMethodName(String requestURI, String matchUrlPrefix) {
        String partsAfterPrefix = StringUtils.substringAfter(requestURI, matchUrlPrefix);
        if (StringUtils.isEmpty(partsAfterPrefix)) {
            // 有可能只传递了前缀
            return StringUtils.EMPTY;
        }

        String partsAfterPrefixWithSlash = partsAfterPrefix.substring(1);
        return StringUtils.substringBefore(partsAfterPrefixWithSlash, "/");
    }
}
